<?php

declare(strict_types=1);

namespace App\Controller\Home\User;

use App\Constants\ErrorCode;
use App\Model\Admin\Admin;
use App\Model\Admin\Roles;
use App\Model\Device;
use App\Model\Distributors;
use App\Model\Feedback;
use App\Model\Order;
use App\Model\Service;
use App\Model\User;
use App\Services\AlipayService;
use App\Services\SmsService;
use Carbon\Carbon;
use Hyperf\Redis\Redis;
use Hyperf\HttpServer\Contract\RequestInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\SimpleCache\InvalidArgumentException;
use RedisException;
use Trait\ResponseMsg;
use App\Model\Normal;
use Hyperf\Di\Annotation\Inject;
use Util\Common;
use Phper666\JWTAuth\JWT;
use Phper666\JWTAuth\Util\JWTUtil;
use App\Services\Wechat;
use App\Controller\AbstractController;


class UserLoginController extends AbstractController
{
    use ResponseMsg;

    #[inject]
    protected User $user;

    protected Redis $redis;
    protected Normal $normal;
    protected JWT $jwt;
    protected Wechat $wechat;

    public function __construct()
    {
        $this->jwt = container()->get(JWT::class);
        $this->redis = container()->get(Redis::class);
        $this->normal = container()->get(Normal::class);
        $this->wechat = container()->get(Wechat::class);
    }

    /**Auth2.0微信登录
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws InvalidArgumentException
     * @throws NotFoundExceptionInterface
     */
    public function login(RequestInterface $request): ResponseInterface
    {
        $params = $request->inputs(['code','type','avatar','nickname']);
        if(!$params['code']){
            return $this->error(1001,'code码不能为空');
        }
        if($params['type'] == $this->user::WECHAT_LOGIN){
            $info = $this->user->wxLogin($params);
        }else{
            $userId = AlipayService::getUserId($params['code']);
            if(isset( $userId['error_response'])){
                return $this->error(1001,$userId['error_response']['sub_msg']);
            }
            $openid = $userId['alipay_system_oauth_token_response']['user_id'];
            if(!$openid){
                return $this->error(1001,'授权失败 请稍后重试');
            }
            $info = $this->user->where('openid',$openid)
                ->where('login_type',$this->user::ALIPAY_LOGIN)
                ->first();
            if(!$info){
                if(!$params['nickname']){
                    $save['nickname'] = '用户'.time();
                }
                if(!$params['avatar']){
                    $save['avatar'] = '//ylc.yimitongxun.com/public/miniprogram/static/image/profile.png';
                }
                $save['openid'] = $openid;
                $save['nickname'] = $params['nickname'];
                $save['avatar'] =  $params['avatar'];
                $save['login_type'] = $this->user::ALIPAY_LOGIN;
                $save['last_login'] = Carbon::now();
                $info = User::create($save);
            }
        }

        if(!$info){
            return $this->error(1001,'操作繁忙 请稍后重试');
        }
        if($info->is_disabled == 2){
            return $this->error(1001,'用户已被禁用 请联系管理员');
        }
        if(isset($params['avatar']) && $params['avatar']){
            $info->avatar = $params['avatar'];
        }
        if(isset($params['nickname']) && $params['nickname']){
            $info->nickname = $params['nickname'];
        }
        $info['last_login'] = Carbon::now();
        $info->save();
        $info = $this->user->makeInfo($info);
        $token = $this->jwt->getToken('application', $info);
        $stringToken = $token->toString();
        $this->jwt->getTTL($stringToken);
        $this->redis->setex($stringToken, $this->jwt->getTTL($stringToken), json_encode($info));
        return $this->success(['token' => $stringToken]);
    }

    /**
     * 检测登录状态
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function getInfo(RequestInterface $request): ResponseInterface
    {
        $data = $this->user->getInfo($request);
        if ($data) {
            return $this->success($data);
        }
        return $this->error(ErrorCode::UNKNOW_INFO);
    }

    public function refreshToken(RequestInterface $request):ResponseInterface{
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }

        $this->jwt->setScene('application');

        $info = $this->user->where('id',$info['id'])
            ->first();

        $info = $this->user->makeInfo($info);
        $token = $this->jwt->getToken('application', $info);
        $stringToken = $token->toString();
        return $this->success(['token' => $stringToken]);
    }

    /**退出登录
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws InvalidArgumentException
     * @throws NotFoundExceptionInterface
     */
    public function logout(RequestInterface $request): ResponseInterface
    {
        $token = $request->getHeaderLine('Authorization');
        $this->jwt->setScene('application');
        $this->jwt->logout($token);
        return $this->success(msg: '退出成功');
    }

    /**保存资料
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function saveInfo(RequestInterface $request):ResponseInterface{
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $nickname = $request->input('nickname');
        $avatar = $request->input('avatar');
        $userInfo = $this->user->where('id',$info['id'])->first();
        if(!$nickname){
            return $this->error(msg:'昵称不能为空');
        }
        $userInfo->nickname = $nickname;
        if($avatar){
            $userInfo->avatar = $avatar;
        }
        $userInfo->save();
        return $this->success(msg: '修改成功');
    }

    /**获取余额
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function getBalance(RequestInterface $request):ResponseInterface{
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $balance = $this->user->where('id',$info['id'])
            ->first(['balance','frozen_balance']);
        return $this->success($balance);
    }

    /**查询用户最近一次购买的服务保障
     * @param RequestInterface $request
     * @return ResponseInterface
     */
    public function checkService(RequestInterface $request):ResponseInterface{
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $data['days'] = 0;
        if($info['is_vip'] > 0){
            if($info['vip_time']){
                $date1 = $info['vip_time'];
                $date2 = date('Y-m-d',time());
                $timestamp1 = strtotime($date1);
                $timestamp2 = strtotime($date2);
                if($timestamp1 > $timestamp2){
                    $diff = $timestamp1 - $timestamp2;
                    $data['days']  = round($diff / (60 * 60 * 24));
                    $serviceId = Order::where('user_id',$info['id'])
                        ->where('service_id','>',0)
                        ->orderBy('id','desc')
                        ->value('service_id');
                    $data['service'] = Service::where('id',$serviceId)->first(['id','name','fee']);
                }
            }
        }
        return $this->success($data);
    }

}
